package de.zainodis.triplog.data.share;

import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.net.Uri;

import java.util.List;

import de.zainodis.triplog.data.persistence.IWeatherDao;

/**
 * Created by fzarrai on 9/13/2014.
 */
public class TriplogContract {

    private static final String TAG = "TriplogContract";

    /**
     * The "Content authority" is a name for the entire content provider, similar to the relationship between a domain name and its website. A convenient string to use for the
     * content authority is the package name for the app, which is guaranteed to be unique on the device.
     */
    public static final String CONTENT_AUTHORITY = "de.zainodis.triplog";
    /**
     * Use CONTENT_AUTHORITY to create the base of all URI's which apps will use to contact the content provider.
     */
    public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY);
    // Possible paths (appended to base content URI for possible URI's)
    // For instance, content://com.example.android.sunshine.app/weather/ is a valid path for
    // looking at weather data. content://com.example.android.sunshine.app/givemeroot/ will fail,
    // as the ContentProvider hasn't been given any information on what to do with "givemeroot".
    // At least, let's hope not. Don't be that dev, reader. Don't be that dev.
    public static final String PATH_WEATHER = "weather";
    public static final String PATH_LOCATION = "location";
    public static final String PATH_TRIP = "trip";
    public static final String PATH_DIARY = "diary";


    //Trip related URIs

    public static final Uri CONTENT_URI_TRIP = BASE_CONTENT_URI.buildUpon().appendPath(PATH_TRIP).build();
    //Points to multiple entries
    public static final String CONTENT_TYPE_TRIP = "vnd.android.cursor.dir/" + CONTENT_AUTHORITY + "/" + PATH_TRIP;
    //Points to one entry via the ID
    public static final String CONTENT_ITEM_TYPE_TRIP = "vnd.android.cursor.item/" + CONTENT_AUTHORITY + "/" + PATH_TRIP;

    //Location related URIs
    public static final Uri CONTENT_URI_LOCATION = BASE_CONTENT_URI.buildUpon().appendPath(PATH_LOCATION).build();
    public static final String CONTENT_TYPE_LOCATION = "vnd.android.cursor.dir/" + CONTENT_AUTHORITY + "/" + PATH_LOCATION;
    public static final String CONTENT_ITEM_TYPE_LOCATION = "vnd.android.cursor.item/" + CONTENT_AUTHORITY + "/" + PATH_LOCATION;


    //Weather related URIs
    public static final Uri CONTENT_URI_WEATHER = BASE_CONTENT_URI.buildUpon().appendPath(PATH_WEATHER).build();
    public static final String CONTENT_TYPE_WEATHER = "vnd.android.cursor.dir/" + CONTENT_AUTHORITY + "/" + PATH_WEATHER;
    public static final String CONTENT_ITEM_TYPE_WEATHER = "vnd.android.cursor.item/" + CONTENT_AUTHORITY + "/" + PATH_WEATHER;

    //Diary related URI
    public static final Uri CONTENT_URI_DIARY = BASE_CONTENT_URI.buildUpon().appendPath(PATH_DIARY).build();


    //Trip related IDs
    static final int TRIP = 100;
    static final int TRIP_ID = 102;


    //Location related IDs
    static final int LOCATION = 300;
    static final int LOCATION_ID = 301;

    //Weather related IDs
    static final int WEATHER = 400;
    static final int WEATHER_WITH_LOCATION = 401;
    static final int WEATHER_WITH_LOCATION_AND_DATE = 402;
    static final int WEATHER_ID = 403;

    //Diary related IDs
    static final int DIARY = 200;
    static final int DIARY_ID = 201;


    public static Uri buildWeatherUri(long id) {
        return ContentUris.withAppendedId(CONTENT_URI_WEATHER, id);
    }

    public static Uri buildWeatherLocation(String locationSetting) {
        return CONTENT_URI_WEATHER.buildUpon().appendPath(locationSetting).build();
    }

    /**
     * @param locationId database id of the location for which weather data should be retrieved.
     * @param startDate  the start date from which weather should be retrieved.
     * @return the resulting uri.
     */
    public static Uri buildWeatherLocationWithStartDate(long locationId, String startDate) {
        return CONTENT_URI_WEATHER.buildUpon()
                .appendQueryParameter(IWeatherDao.COLUMN_DATETEXT, startDate)
                .appendQueryParameter(IWeatherDao.COLUMN_FK_LOCATION_ID, String.valueOf(locationId)).build();
    }

    public static Uri buildWeatherLocationWithDate(String locationSetting, String date) {
        return CONTENT_URI_WEATHER.buildUpon().appendPath(locationSetting).appendPath(date).build();
    }

    /**
     * Creates a trip URI with an appended id..
     *
     * @param id the trip id
     * @return the URI with the appended id.
     */
    public static Uri buildTripUri(long id) {
        //Builds a uri for a trip content insert for instance
        return ContentUris.withAppendedId(CONTENT_URI_TRIP, id);
    }

    public static Uri buildLocationUri(long id) {
        //Builds a uri for a location content insert for instance
        return ContentUris.withAppendedId(CONTENT_URI_LOCATION, id);
    }

    /**
     * Creates a trip URI with an appended id..
     *
     * @param id the diary id
     * @return the URI with the appended id.
     */
    public static Uri buildDiaryUri(long id) {
        //Builds a uri for a diary content insert for instance
        return ContentUris.withAppendedId(CONTENT_URI_DIARY, id);
    }

    public static String getLocationSettingFromUri(Uri uri) {
        return uri.getPathSegments().get(1);
    }

    public static String getDateFromUri(Uri uri) {
        return uri.getPathSegments().get(2);
    }

    public static String getStartDateFromUri(Uri uri) {
        return uri.getQueryParameter(IWeatherDao.COLUMN_DATETEXT);
    }

    /**
     * Inserts the given ContentValues into the database. Requires the location to have already been added.
     *
     * @return true if inserting the given values was successful; false otherwise.
     */
    public static boolean insertWeather(Context context, ContentValues values) {
        Uri weatherInsertUri = context.getContentResolver().insert(CONTENT_URI_WEATHER, values);
        return weatherInsertUri != null;
    }

    /**
     * Inserts the given ContentValues into the database. Requires the location to have already been added.
     *
     * @return true if inserting the given values was successful; false otherwise.
     */
    public static boolean insertWeather(Context context, List<ContentValues> values) {
        boolean result = true;
        for (ContentValues value : values) {
            result &= insertWeather(context, value);

            if (!result) {
                break;
            }
        }
        return result;
    }


    static UriMatcher buildUriMatcher() {
        // All paths added to the UriMatcher have a corresponding code to return when a match is
        // found. The code passed into the constructor represents the code to return for the root
        // URI. It's common to use NO_MATCH as the code for this case.
        final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
        final String authority = CONTENT_AUTHORITY;
        //Weather related URIs
        matcher.addURI(authority, PATH_WEATHER, WEATHER);
        matcher.addURI(authority, PATH_WEATHER + "/#", WEATHER_ID);
        matcher.addURI(authority, PATH_WEATHER + "/*", WEATHER_WITH_LOCATION);
        matcher.addURI(authority, PATH_WEATHER + "/*/*", WEATHER_WITH_LOCATION_AND_DATE);
        //Location related URIs
        matcher.addURI(authority, PATH_LOCATION, LOCATION);
        matcher.addURI(authority, PATH_LOCATION + "/#", LOCATION_ID);
        //Trip related URIs
        matcher.addURI(authority, PATH_TRIP + "/#", TRIP_ID);
        matcher.addURI(authority, PATH_TRIP, TRIP);
        //Diary related URIs
        matcher.addURI(authority, PATH_DIARY + "/#", DIARY_ID);
        matcher.addURI(authority, PATH_DIARY, DIARY);
        return matcher;
    }
}
